package com.andy.ui.view;

import android.content.Context;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextUtils;
import android.util.AttributeSet;

import androidx.annotation.NonNull;

import com.andy.ui.view.ClearEditText;

import java.util.ArrayList;
import java.util.List;

/**
 * 作者:LuoFan
 * 创建时间:2022-5-11
 * 描述: 手机号输入框
 */
public class PhoneEditText extends ClearEditText {

    private TextChangeListener textListener;
    private StringBuffer mStringBuffer = new StringBuffer();
    /**
     * 分割符
     */
    private String separator = "";
    /**
     * 分割符插入位置规则
     */
    private int[] RULES = {3, 4, 4};
    /**
     * 最大输入长度
     */
    private int MAX_INPUT_LENGTH = 11;

    public PhoneEditText(Context context) {
        super(context);
        initView();
    }

    public PhoneEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public PhoneEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        setInputType(InputType.TYPE_CLASS_NUMBER);
        setFilters(new InputFilter[]{new InputFilter.LengthFilter(11)});
    }

    public void setTextListener(TextChangeListener changeListener) {
        textListener = changeListener;
    }

    /**
     * 设置分割符
     *
     * @param separator 分隔符，默认为空格
     */
    public void setSeparator(String separator) {
        if (!TextUtils.isEmpty(separator)) {
            String originalText = removeSpecialSeparator(separator);
            this.separator = separator;
            if (!TextUtils.isEmpty(originalText)) {
                setText(originalText);
                setSelection(getText().length());
            }
            setupMaxInputLength();
        }
    }

    public int getMaxInputLength() {
        return MAX_INPUT_LENGTH;
    }

    /**
     * 更新最大输入长度
     */
    private void setupMaxInputLength() {
        MAX_INPUT_LENGTH = MAX_INPUT_LENGTH + RULES.length - 1;
        //更新LengthFilter
        InputFilter[] filters = this.getFilters();
        List<InputFilter> filterList = new ArrayList<>();
        for (int i = 0; i < filters.length; i++) {
            InputFilter filter = filters[i];
            if (filter instanceof InputFilter.LengthFilter) {

            } else {
                filterList.add(filter);
            }
        }
        addLengthFilter(filterList);
    }


    private void addLengthFilter(List<InputFilter> filterList) {
        InputFilter[] newFilters = new InputFilter[filterList.size() + 1];
        for (int i = 0; i < filterList.size(); i++) {
            newFilters[i] = filterList.get(i);
        }
        InputFilter.LengthFilter lengthFilter = new InputFilter.LengthFilter(MAX_INPUT_LENGTH);
        newFilters[newFilters.length - 1] = lengthFilter;
        setFilters(newFilters);
    }

    public String removeSpecialSeparator(String specialSeparator) {
        return getText().toString().replace(specialSeparator, "");
    }

    public String getRemoveSeparatorContent() {
        return getText().toString().replace(separator, "").trim();
    }

    @Override
    public void afterTextChanged(Editable s) {
        super.afterTextChanged(s);
        String content = s.toString();
        if (content.length() == 1) {
            if (!content.equals("1")) {
                setText("");
                return;
            }
        }
        if (content.length() > 1) {
            String firstValue = content.substring(0, 1);
            if (firstValue.equals("0")) {
                if (content.length() >= 2) {
                    String newContent = content.substring(1);
                    setText(newContent);
                    int length = getText().toString().length();
                    if (length > 0) {
                        setSelection(length);
                    }
                } else {
                    //刚好只有1位
                    setText("");
                }
                return;
            }
        }

        if (content.length() == 2) {
            int secondIndex = 0;
            if (!TextUtils.isEmpty(content.substring(1))) {
                secondIndex = Integer.parseInt(content.substring(1));
            }
            if (secondIndex < 3) {
                setText(content.substring(0, 1));
                int contentLength = getText().toString().length();
                setSelection(contentLength);
                return;
            }
        } else if (content.length() > 2) {
            int secondIndex = 0;
            if (!TextUtils.isEmpty(content.substring(1, 2))) {
                secondIndex = Integer.parseInt(content.substring(1, 2));
            }
            if (secondIndex < 3) {
                StringBuilder newContent = new StringBuilder();
                newContent.append(content.substring(0, 1));
                newContent.append(content.substring(2));
                setText(newContent.toString());
                int contentLength = getText().toString().length();
                setSelection(contentLength);
                return;
            }
        }
        if (textListener != null) {
            textListener.onChanged(content);
        }
        if (!TextUtils.isEmpty(separator) && !TextUtils.equals(s, mStringBuffer)) {
            //删除mStringBuffer中的文本
            mStringBuffer.delete(0, mStringBuffer.length());
            //添加分隔符
            mStringBuffer.append(handleText(s, RULES, separator));
            //删除多余字符
            if (mStringBuffer.length() > MAX_INPUT_LENGTH) {
                mStringBuffer.delete(MAX_INPUT_LENGTH, mStringBuffer.length());
            }
            final int currSelectStart = getSelectionStart();
            //计算分隔符导致的光标offset
            int separatorOffset = calculateSeparatorOffset(s, mStringBuffer, currSelectStart);
            setText(mStringBuffer);
            //计算并设置当前的selectStart位置
            int selectStart = currSelectStart + separatorOffset;
            if (selectStart < 0) {
                selectStart = 0;
            } else if (selectStart > mStringBuffer.length()) {
                selectStart = mStringBuffer.length();
            }
            setSelection(selectStart);
        }
    }

    /**
     * 计算符号的offset
     *
     * @param before
     * @param after
     * @param selectionStart
     * @return
     */
    private int calculateSeparatorOffset(@NonNull CharSequence before, @NonNull CharSequence after, int selectionStart) {
        int offset = 0;
        final int beforeLength = before.length();
        final int afterLength = after.length();
        final int length = afterLength > beforeLength ? beforeLength : afterLength;
        for (int i = 0; i < length; i++) {
            if (i >= selectionStart) {
                break;
            }
            String bc = String.valueOf(before.charAt(i));
            String ac = String.valueOf(after.charAt(i));
            if (TextUtils.equals(bc, separator) && !TextUtils.equals(ac, separator)) {
                offset--;
            } else if (!TextUtils.equals(bc, separator) && TextUtils.equals(ac, separator)) {
                offset++;
            }
        }
        return offset;
    }

    public String handleText(Editable s, int[] rules, String separator) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0, length = s.length(); i < length; i++) {
            String c = String.valueOf(s.charAt(i));
            if (!TextUtils.equals(c, separator)) {
                stringBuffer.append(c);
            }
            if (length != stringBuffer.length() && isSeparationPosition(rules, stringBuffer.length())) {
                stringBuffer.append(separator);
            }
        }
        return stringBuffer.toString();
    }

    private static boolean isSeparationPosition(int[] RULES, int length) {
        if (RULES == null) {
            return false;
        }
        int standardPos = 0;
        int offset = 0;
        for (int pos : RULES) {
            standardPos += pos;
            if (length == standardPos + offset++) {
                return true;
            }
        }
        return false;
    }

    public interface TextChangeListener {
        void onChanged(String content);
    }

    public void setMAX_INPUT_LENGTH(int MAX_INPUT_LENGTH) {
        this.MAX_INPUT_LENGTH = MAX_INPUT_LENGTH;
    }

    public void setRULES(int[] RULES) {
        this.RULES = RULES;
    }
}
